6W - EKS api 서버 접근 보안
개요
이전까지 쿠버네티스와는 관련되나, eks와는 관련이 없는 보안 내용들을 다뤘다.
이번 문서부터는 eks에서 제공하는 각종 보안 기능들을 보도록 한다.
이중, api 서버에 대해서 제공하는 기능을 보도록 한다.
사전 지식
온프레미스 환경에서 api 서버를 접근하는 주체가 누구인지 검증하는 것은 전적으로 api 서버에서 관리된다.
그러나 EKS 환경에서는 조금 다른 방식을 제공하는데, AWS의 IAM에 있는 유저 정보를 바탕으로 인증을 하게 된다.
아무래도 AWS에서 api 서버를 관리하니, api 서버로 접근하는 사람을 인증하는 것 역시 AWS 차원에서 관리를 하는 것이 당연하다고 볼 수 있겠다.
다시 말해 시큐리티#1. 인증(Authentication) 단계를 전적으로 AWS에서 관리한다는 것이다.
(참고로 당연히 클러스터 내부에서만 활동하는, 서비스 어카운트의 인증과는 관련 없다.)
첫번째는 클러스터 조작을 하는 kube-apiserver에 대한 보안이다.
그렇다면 여기에서 한 가지 문제가 생기는데, 여차저차 AWS의 신원이 증명됐다고 쳐보자.
근데 어떤 IAM 유저인지 알았다고 해서 클러스터에서 해당 유저를 명확하게 식별할 수 있는가?
즉, AWS에서의 신원과 클러스터 내의 신원을 매핑시키는 과정이 api 서버 보안에서 핵심 관건이라고 할 수 있다.
configmap
먼저 말하지만 곧 이 방식은 없어질 것이다.
이건 iam 신원과 매칭되는 클러스터 신원을 ConfigMap으로 관리하는 방식이다.
기본적으로 사용자가 클러스터 조작을 가할 때 다음의 과정이 일어난다.[1]
요약해서 흐름을 보겠다.
- 로컬에서는 STS로 임시 자격 증명을 얻어내고 이걸 이용해 api 서버에 접근한다.
- api 서버는 웹훅 토큰 인증 방식을 통해, aws-iam-authentication-server에 인증을 맡긴다.
- 참고로 aias 서버는 컨트롤 플레인에 위치해있을 거라, 일반 사용자가 확인할 수 없다.
- aias 서버는 받은 토큰을 이용해 IAM api와 통신해 AWS 상의 유저, 그룹 등의 신원 정보를 받아낸다.
- 신원 정보를 사전에 설정된 클러스터 내에서의 신원 정보와 매핑시켜 인증 단계를 통과시킨다.
이 마지막 매핑 단계에서 configmap에 저장된 정보를 바탕으로 클러스터 신원을 매핑시킨다는 것이 핵심이다.
이 컨피그맵의 경우, 저 roleArn으로 들어온 요청일 때 aias 서버는 username은 system:node:인스턴스 이름
, 그룹은 system:nodes
로 매핑을 시켜서 인증 단계를 통과시키게 되는 것이다.
매핑이 어떻게 돼야 하는지 자체는 운영자가 미리 세팅을 진행해야 한다.
aias는 매핑된 정보를 컨피그맵에서 불러와 적절하게 정보를 넣어주는 역할만 수행한다.
eksctl create iamidentitymapping --cluster $CLUSTER_NAME --username testuser --group system:masters --arn arn:aws:iam::$ACCOUNT_ID:user/testuser
이런 식으로 명령을 내리면 --arn
에 있는 iam 유저가 username:group
으로 클러스터 신원에 매핑된 정보가 컨피그맵에 저장된다.
단점
이 방식의 단점은 명백하다.
AWS에서는 위의 명령어와 같은 식으로 인증 설정을 조작하도록 이야기하지만, 일단 configmap은 쉽게 클러스터 내부에서 수정이 가능하다.
즉, 악성 내부 관리자가 인증 조작을 하는 것이 너무 쉽다.
여차하면 실수를 하는 것도 가능할 것이다.
물론 기록은 남겠지만, 이렇게 쉽게 휴먼 에러를 발생시킬 수 있는 방식 자체가 좋은 운영 방식이 아니다.
ConfigMap#immutable을 사용하는 방향도 생각할 수 있겠다.
그것도 그래봤자인 게, edit만 안 되는 거지 삭제했다 재생성하는 건 가능하기에 여전히 불안한 방식임에는 변함이 없다.
Access Entry
그래서 다음으로 나온 방식이 바로 Access Entry이다.[2]
이 방식은 eks api를 활용한 매핑 방식으로, 매핑 정보가 AWS 상에서 관리된다.
그러니 클러스터에서 실수를 한다던가 하는 일은 절대 발생하지 않고, 인증에 대한 관리 영역이 전적으로 AWS 위에서 성립한다는 장점이 있다.
초기 순서는 configMap과 동일하게 STS에서 임시자격증명을 얻어서 api 서버로 요청이 날아가는 것으로 시작한다.
그리고 웹훅으로 인증을 수행하게 되는데, 이때는 eks api를 호출해 요청의 aws iam 신원 정보가 어떤 클러스터 신원 정보와 매핑되는지 확인하고 이를 적용한다.
그런데 이 방식에서는 조금 차이점이 생긴다.
바로 인가에 대한 부분을 어느 정도 AWS에서 관리하게 된다는 것이다.
구체적으로는 AWS에서는 IAM 정책과 독립되는, 액세스 엔트리를 위한 관리형 정책을 따로 제공한다.[3]
쿠버네티스에서 기본적으로 세팅된 쿠버 RBAC#유저 중심 롤을 정책으로 규정해두었으며, 액세스 엔트리를 만들 때 이 정책들을 명시하여 사용할 수 있다.
즉, 액세스 엔트리는 클러스터 내의 그룹에 신원을 매핑시켜 클러스터 차원에서 인가를 수행하거나, 아예 관리형 정책을 통해 AWS측에서 인가까지 수행하게 하는 두 가지 방식으로 사용할 수 있다는 말이다.
# 관리형 정책에 매핑시키기
aws eks create-access-entry --cluster-name 클러 이름 --principal-arn IAM 유저
aws eks associate-access-policy --cluster-name 클러 이름 --principal-arn IAM 유저
--policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy --access-scope type=cluster
# 쿠버 그룹에 매핑시키기
aws eks create-access-entry --cluster-name 클러 이름 --principal-arn IAM 유저 --kubernetes-groups 쿠버 그룹
관리형 정책을 매핑시킬 때는 (귀찮지만) 두 번의 과정이 필요하다.
실습 진행
기본 확인
콘솔에 eks쪽 access 탭에 들어가면 관련한 정보가 확인된다.
현재 액세스 방식은 두 가지가 혼용되고 있다.
우선되는 것은 eks api로, 여기에서 인증을 수행할 수 없을 때 configmap을 참조하게 된다.
액세스 엔트리에는 다양한 정보가 들어가 있는데, 노드와 이 클러스터를 만든 사용자에 대한 인증을 위한 설정이 돼있다.
첫번째 엔트리는 콘솔을 통해 클러스터를 확인할 수 있도록 하는 엔트리이다.
그리고 가장 마지막 엔트리가 현재 사용자인 나를 위해 설정된 엔트리로, 관리자 정책이 부여되는 것을 확인할 수 있다.
aws eks list-access-policies
aws eks list-access-entries --cluster-name $CLUSTER_NAME
eks 차원에서 제공하는 관리형 접근 정책에는 여러 종류가 있어서 이것을 활용해도 된다.
현재 만들어진 엔트리를 cli로도 확인할 수 있다.
aws eks list-associated-access-policies --cluster-name --principal-arn
해당 엔트리에 어떤 정책들이 엮였는지 확인하고 싶다면 이렇게 해주면 된다.
추가적으로 아직 남은 configmap도 살짝 보자면..
k -n kube-system get cm aws-auth -oyaml
configmap 파일 내용물을 보면 노드들의 arn이 클러스터에서 node로 매핑되도록 된 것을 확인할 수 있다.
액세스 엔트리 실습
configmap 방식은 곧 deprecated될 거라 굳이 실습하지 않고, 액세스 엔트리를 사용하는 방식을 사용해본다.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-viewer-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list", "get", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-viewer-binding
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pod-viewer-role
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: pod-viewer
먼저 클러스터롤과 바인딩을 만들어준다.
aws iam create-user --user-name testuser
aws iam create-access-key --user-name testuser
aws configure --profile test
다음 유저를 만들어준다.
프로필을 따로 설정하여 여러 유저로 다룰 수 있게 프로필 세팅을 진행했다.
이 유저는 IAM에 대한 어떠한 정책도 가지고 있을 필요가 없다.
eks get token은 자격증명을 가지고만 있다면 실행이 가능하기 때문이다.
...
- context:
cluster: arn:aws:eks:ap-northeast-2:134555352826:cluster/terraform-eks
user: eks-test
name: eks-test
...
- name: eks-test
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- --region
- ap-northeast-2
- eks
- get-token
- --cluster-name
- terraform-eks
- --profile
- test
- --output
- json
command: aws
env: null
interactiveMode: IfAvailable
provideClusterInfo: false
그 다음 kubeconfig에서 유저와 컨텍스트를 하나 추가한다.
유저의 부분에서 프로필을 사용하는 식으로 지정한 것을 확인할 수 있다.
현재 컨텍스트만 바꿔주면, 이제 내가 하는 테스트 유저로서 동작을 할 수 있게 된다!
CLUSTER_NAME=terraform-eks
ACCOUNT_ID=
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --user-name testuser
aws eks create-access-entry --cluster-name $CLUSTER_NAME --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/testuser --kubernetes-groups pod-viewer
마지막으로 액세스 엔트리를 만들어 매핑을 진행한다.
보다시피 이 유저는 정직하게 default 네임스페이스의 pod를 보는 권한만 부여받았기에, 관련한 동작만 수행할 수 있다.
콘솔에서도 해당 유저는 그룹만 지정받는 것을 확인할 수 있다.
AWS는 어떻게 인가까지 수행해주는 걸까?
인가는 Authorization#Webhook으로 이뤄지는 것으로 추측된다.[4]
k auth can-i --list
를 하게 될 경우 웹훅을 통해 이뤄지는 인가를 제외, 현재 유저가 할 수 있는 동작들을 확인할 수 있다.
그런데 관리자 권한을 가진 유저의 권한은 system:authenticated
인 그룹이 가진 권한만 보이는 것이 확인된다.
이는 웹훅을 통해 인가가 이뤄지고 있다는 단서 중 하나이다.
두번째로, audit 로그를 보면 인가가 된 이유에 대한 내용이 명시된다.
어떠한 근거로 요청이 허가됐는지에 대한 내용이 담긴다.
여기에서는 클러스터 롤 바인딩과 클러스터 롤에 대한 이야기가 언급이 있으나, 이건 실제 클러스터에 존재하지 않는다.
이러한 인가 관련 사항이 AWS 측에서 관리되고 있음을 알 수 있는 대목이다.
그렇다고 위의 eks에서 관리해주는 정책들로만 인가 가능한 게 아닐까 걱정할 필요는 없다.
쿠버의 인가는 다양한 모듈이 있을 때 어느 한 모듈이 허가 결정을 내리기만 해도 요청이 통과되므로, 여전히 기본 쿠버의 RBAC도 작동한다.
관련한 워크숍에서도 클러스터 내에서 그룹 신원을 규정한 뒤에 액세스 엔트리에 그룹을 명시하면 해당 그룹에 대한 쿠버의 RBAC가 작동하는 것을 확인할 수 있다.[5]
결론
eks api 서버에 접근하기 위해서는 먼저 aws 상에서의 신원을 검증받고, 이 신원을 클러스터로 매핑시키는 과정이 필요하다.
최근에 나온 access entry 방식은 이러한 복잡한 과정을 상당히 단순화시켜주는 동시에 사용자 에러도 줄여주기에, eks를 활용할 경우 적극적으로 이용하는 것이 좋다.
다만 아쉬운 것은 이 기능을 클러스터 내부 차원에서 다룰 수 없다는 것이다.
이건 개인적인 추측이지만, 차후에는 CRD를 만들어서 관리할 수 있도록 발전되지 않을까 한다.
이전 글, 다음 글
다른 글 보기
이름 | index | noteType | created |
---|---|---|---|
1W - EKS 설치 및 액세스 엔드포인트 변경 실습 | 1 | published | 2025-02-03 |
2W - 테라폼으로 환경 구성 및 VPC 연결 | 2 | published | 2025-02-11 |
2W - EKS VPC CNI 분석 | 3 | published | 2025-02-11 |
2W - ALB Controller, External DNS | 4 | published | 2025-02-15 |
3W - kubestr과 EBS CSI 드라이버 | 5 | published | 2025-02-21 |
3W - EFS 드라이버, 인스턴스 스토어 활용 | 6 | published | 2025-02-22 |
4W - 번외 AL2023 노드 초기화 커스텀 | 7 | published | 2025-02-25 |
4W - EKS 모니터링과 관측 가능성 | 8 | published | 2025-02-28 |
4W - 프로메테우스 스택을 통한 EKS 모니터링 | 9 | published | 2025-02-28 |
5W - HPA, KEDA를 활용한 파드 오토스케일링 | 10 | published | 2025-03-07 |
5W - Karpenter를 활용한 클러스터 오토스케일링 | 11 | published | 2025-03-07 |
6W - PKI 구조, CSR 리소스를 통한 api 서버 조회 | 12 | published | 2025-03-15 |
6W - api 구조와 보안 1 - 인증 | 13 | published | 2025-03-15 |
6W - api 보안 2 - 인가, 어드미션 제어 | 14 | published | 2025-03-16 |
6W - EKS 파드에서 AWS 리소스 접근 제어 | 15 | published | 2025-03-16 |
6W - EKS api 서버 접근 보안 | 16 | published | 2025-03-16 |
7W - 쿠버네티스의 스케줄링, 커스텀 스케줄러 설정 | 17 | published | 2025-03-22 |
7W - EKS Fargate | 18 | published | 2025-03-22 |
7W - EKS Automode | 19 | published | 2025-03-22 |
8W - 아르고 워크플로우 | 20 | published | 2025-03-30 |
8W - 아르고 롤아웃 | 21 | published | 2025-03-30 |
8W - 아르고 CD | 22 | published | 2025-03-30 |
8W - CICD | 23 | published | 2025-03-30 |
9W - EKS 업그레이드 | 24 | published | 2025-04-02 |
10W - Vault를 활용한 CICD 보안 | 25 | published | 2025-04-16 |
11W - EKS에서 FSx, Inferentia 활용하기 | 26 | published | 2025-04-18 |
11주차 - EKS에서 FSx, Inferentia 활용하기 | 26 | published | 2025-05-11 |
12W - VPC Lattice 기반 gateway api | 27 | published | 2025-04-27 |
관련 문서
이름 | noteType | created |
---|---|---|
쿠버 RBAC | knowledge | 2024-09-02 |
시큐리티 | knowledge | 2025-01-12 |
Secret | knowledge | 2025-01-12 |
파드 시큐리티 스탠다드 | knowledge | 2025-01-13 |
ServiceAccount | knowledge | 2025-01-13 |
API 접근 제어 우회 | knowledge | 2025-01-13 |
멀티 테넌시 | knowledge | 2025-01-13 |
Authentication | knowledge | 2025-01-13 |
리눅스 커널 보안 제약 | knowledge | 2025-01-14 |
보안 체크리스트 | knowledge | 2025-01-14 |
Authorization | knowledge | 2025-01-19 |
Admission Control | knowledge | 2025-01-20 |
Admission Webhook | knowledge | 2025-01-20 |
Audit | knowledge | 2025-03-12 |
Validation Admission Policy | knowledge | 2025-03-17 |
Kyverno | knowledge | 2025-03-17 |
E-쿠버네티스 인증 실습 | topic/explain | 2025-01-21 |
E-api 서버 감사 | topic/explain | 2025-01-21 |
E-쿠버 RBAC 권한 상승 방지 실습 | topic/explain | 2025-03-16 |
E-Kyverno 기본 실습 | topic/explain | 2025-03-17 |
참고
https://aws.amazon.com/ko/blogs/containers/a-deep-dive-into-simplified-amazon-eks-access-management-controls/ ↩︎
https://docs.aws.amazon.com/eks/latest/userguide/access-policy-permissions.html ↩︎
https://aws.amazon.com/ko/blogs/containers/a-deep-dive-into-simplified-amazon-eks-access-management-controls/ ↩︎
https://catalog.workshops.aws/eks-immersionday/en-US/access-management/3-kubernetes-groups ↩︎